//
//  RosterListViewController.m
//  000-ChatChair
//
//  Created by 李晓东 on 2018/4/18.
//  Copyright © 2018年 PeanutXu. All rights reserved.
//

#import "RosterListViewController.h"
#import "ChatViewController.h"
#import "AppDelegate.h"
#define sectionHeaderHeight 34

@interface RosterListViewController () <XMPPRosterDelegate, UITextFieldDelegate, RosterListDelegate>
@property (nonatomic, strong) NSArray *headers;
@property (nonatomic, strong) NSMutableArray *onlineRosters;
@property (nonatomic, strong) NSMutableArray *offlineRosters;
@property (nonatomic, strong) NSMutableArray *tryRosters;

@property (nonatomic, strong) XMPPRoster *roster;

@end

@implementation RosterListViewController{
    AppDelegate *_app;
    NSMutableArray<NSNumber*> *_status;
    NSMutableArray *_currentRosters;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.tableView.delegate = self;
    _app = (AppDelegate *)[UIApplication sharedApplication].delegate;
    _app.rosterListDelegate = self;
    CGFloat screenWidth = self.view.frame.size.width;
    
    UIView *headerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, screenWidth, 80)];
    [self.tableView setTableHeaderView:headerView];
    
    CGFloat marginX = screenWidth * 0.05;
    UILabel *ownerLabel = [[UILabel alloc]initWithFrame:CGRectMake(marginX, 20, screenWidth - marginX * 2, 29)];
    [ownerLabel setText:[NSString stringWithFormat:@"%@的好友", _app.xmppStream.myJID.user]];
    [headerView addSubview:ownerLabel];
    
    UITextField *rosterField = [[UITextField alloc]initWithFrame:CGRectMake(marginX, 50, screenWidth - marginX * 2, 30)];
    [rosterField setPlaceholder:@"查找好友"];
    [rosterField setClearButtonMode:UITextFieldViewModeWhileEditing];
    [rosterField setReturnKeyType:UIReturnKeySearch];
    [rosterField setDelegate:self];
    
    [headerView addSubview:rosterField];

    _status = [NSMutableArray arrayWithArray:@[@NO, @NO, @NO]];
    _currentRosters = [NSMutableArray array];
    _headers = @[@"在线好友", @"离线好友", @"尝试添加的好友"];
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"li"];
    
    [self setupRoster];
    
    _onlineRosters = [NSMutableArray array];
    _offlineRosters = [NSMutableArray array];
    _tryRosters = [NSMutableArray array];;
    [self.roster fetchRoster];
//    [self tempMethod];
}



- (void)tempMethod {
    _onlineRosters = @[@1, @2, @3];
    _offlineRosters = @[@4, @5, @8];
    _tryRosters = @[@6, @7];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    return _headers.count;
}

// 滑动操作
- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewRowAction *deleteRoWAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"删 除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
        NSArray *group = indexPath.section == 0 ? _onlineRosters : (indexPath.section == 1 ? _offlineRosters : _tryRosters);
        XMPPJID *xmppjid = [XMPPJID jidWithString:group[indexPath.row]];
        [_roster removeUser:xmppjid];
    }];
    return @[deleteRoWAction];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    
    return section == 0 ? (_status[section].boolValue ? _onlineRosters.count : 0) : (section == 1 ? (_status[section].boolValue ? _offlineRosters.count : 0) : (_status[section].boolValue ? _tryRosters.count : 0));
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"li" forIndexPath:indexPath];
    NSArray *arr = indexPath.section == 0 ? _onlineRosters : (indexPath.section == 1 ? _offlineRosters : _tryRosters);
    cell.textLabel.text = arr[indexPath.row];
    
    if ( _app.historyMessage[arr[indexPath.row]] != nil ) {
        _app.historyMessage[arr[indexPath.row]].count;
    }
    return cell;
}


- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
    UIView *headerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 1, sectionHeaderHeight)];
    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(30, (sectionHeaderHeight - 20) / 2, 160, 20)];
    [label setText:_headers[section]];
    [headerView addSubview:label];
    
    UIImageView *icon = [[UIImageView alloc]initWithImage:_status[section].boolValue ? [UIImage imageNamed:@"zhan.gif"] : [UIImage imageNamed:@"zhe.gif"]];
    
    [icon setFrame:CGRectMake(10, (sectionHeaderHeight - 16)/2, 16, 16)];
    [headerView addSubview:icon];
    [headerView setTag:section];
    [headerView setUserInteractionEnabled:YES];
    [headerView addGestureRecognizer:[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(display:)]];
    return headerView;
    
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    NSArray *arr = indexPath.section == 0 ? _onlineRosters : (indexPath.section == 1 ? _offlineRosters : _tryRosters);
    
    ChatViewController *viewController = (ChatViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"chatScene"];
    [viewController setSession:arr[indexPath.row]];
    [self presentViewController:viewController animated:YES completion:nil];
}

- (void)display:(UIGestureRecognizer *)gesture{
    NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:gesture.view.tag];
    _status[gesture.view.tag] = [NSNumber numberWithBool:!_status[gesture.view.tag].boolValue];
    
    [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];
    
}

            
// 创建并初始化 XMPPRoster
- (void)setupRoster {
    XMPPRosterCoreDataStorage *rosterStorage = [[XMPPRosterCoreDataStorage alloc]init];
    _roster = [[XMPPRoster alloc]initWithRosterStorage:rosterStorage];
    [_roster activate:_app.xmppStream];
    [_roster addDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
    
}

// 键盘 return 的事件
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
    [textField resignFirstResponder];
    NSString *rosterText = textField.text;
    XMPPJID *jid = [XMPPJID jidWithString:[NSString stringWithFormat:@"%@%@", rosterText , HOST_SUFFIX]];
    [_roster subscribePresenceToUser:jid];
    textField.text = @"";
    return YES;
}

- (void)xmppRoster:(XMPPRoster *)sender didReceiveRosterPush:(XMPPIQ *)iq{
    NSLog(@"done");
}

// 收到好友信息（包括加载好友、添加好友、被对方删除）都激发该方法
- (void)xmppRoster:(XMPPRoster *)sender didReceiveRosterItem:(DDXMLElement *)item{
    // 获取jid属性获取好友名
    NSString* rosterName = [item attributeStringValueForName:@"jid"];
    NSString* type = [item attributeStringValueForName:@"subscription"];
    NSString* ask = [item attributeStringValueForName:@"ask"];
    
    // 如果type为remove,且ask==nil，表明主动删除好友
    if ([type isEqualToString:@"remove"] && ask == nil) {
        [_onlineRosters removeObject: rosterName];
        [_offlineRosters removeObject: rosterName];
        NSLog(@"如果type为remove,且ask==nil，表明主动删除好友");
        [_currentRosters removeObject:rosterName];
    }
    // 如果type为remove,且ask==subscribe，表明主动删除尝试添加的好友
    else if ([type isEqualToString:@"remove"] && [ask isEqualToString:@"subscribe"]) {
        [_tryRosters removeObject:rosterName];
        NSLog(@"如果type为remove,且ask==subscribe，表明主动删除尝试添加的好友");
        [_currentRosters removeObject:rosterName];
    }
    // 如果type为to,且ask==nil，表明被该好友删除
    if ([type isEqualToString:@"to"] && ask == nil) {
        [_onlineRosters removeObject:rosterName];
        [_offlineRosters removeObject:rosterName];
        NSLog(@"如果type为to,且ask==nil，表明被该好友删除");
        [_currentRosters removeObject:rosterName];
    }
    // 如果type为none,且ask=="subscribe"，表明为正尝试添加该好友
    else if ([type isEqualToString:@"none"] && ask != nil &&
             [ask isEqualToString:@"subscribe"]) {
        // 避免重复添加
        if (![_tryRosters containsObject:rosterName]) {
            [_tryRosters addObject:rosterName];
            [_currentRosters addObject:rosterName];
        }
        NSLog(@"如果type为none,且ask==\"subscribe\"，表明为正尝试添加该好友");
    }
    // 如果type为both,且ask==nil，表明为已添加的好友
    if ([type isEqualToString:@"both"] && ask == nil) {
        if ([_tryRosters containsObject:rosterName]
            // 避免重复添加
            && ![_onlineRosters containsObject:rosterName]){
            [_tryRosters removeObject:rosterName];
            [_onlineRosters addObject:rosterName];
            NSLog(@"如果type为both,且ask==nil，表明为已添加的好友");
        }
        // 且该用户不是在线用户
        if (![_onlineRosters containsObject:rosterName] &&
            // 避免重复添加
            ![_offlineRosters containsObject:rosterName]){
            [_offlineRosters addObject:rosterName];
            NSLog(@"且该用户不是在线用户");
            [_currentRosters removeObject:rosterName];

        }
    }
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];

    });
}

// 收到好友请求时激发该方法
- (void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscriptionRequest:(XMPPPresence *)presence{
    NSString *userName = [presence from].user;
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"TIps" message:[NSString stringWithFormat:@"%@ wannt to be your friend", userName] preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"Sure" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        // 该方法还回再调用- didReceiveRosterItem方法刷新一遍数据
        [_roster acceptPresenceSubscriptionRequestFrom:[presence from] andAddToRoster:YES];
    }];
    UIAlertAction *rejectAction = [UIAlertAction actionWithTitle:@"Disagree" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        [_roster rejectPresenceSubscriptionRequestFrom:[presence from]];
        // 说明见下方 A
        [_roster removeUser:[presence from]];
    }];
    [alertController addAction:confirmAction];
    [alertController addAction:rejectAction];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self presentViewController:alertController animated:YES completion:nil];
        
    });
    
}

- (void)xmppRosterDidEndPopulating:(XMPPRoster *)sender{
    // 判断用户是否在线
    [self checkOnlineStatus];
    dispatch_sync(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];

    });
}

- (void)checkOnlineStatus {
    NSMutableArray *tempArray = [NSMutableArray array];
    for (NSString *roster in _offlineRosters.copy) {
        NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://lixiaodongdemac-mini.local:9090/plugins/presence/status?jid=%@&type=xml", roster]];
        
        NSError *error;
        NSString *str = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
        if (error == nil) {
            if (![str containsString:@"type=\"unavailable\""]) {
                [_offlineRosters removeObject:roster];
                [_onlineRosters addObject:roster.copy];
                
            }
        } else {
            NSLog(@"error--%@", error);

        }
        
    }
    [_currentRosters removeAllObjects];
    _currentRosters = _offlineRosters.mutableCopy;
    tempArray = _onlineRosters;

}

- (void)onOrOff:(NSString *)userId isOn:(BOOL)isOn{
    NSMutableString *mutableString = [NSMutableString stringWithString:userId];
    if (![userId containsString:@"@lixiaodongdemac-mini.local"]) {
        [mutableString appendString:@"@lixiaodongdemac-mini.local"];
    }
    if (isOn) {
        if (![_onlineRosters containsObject:mutableString.copy]) {
            [_onlineRosters addObject:mutableString.copy];
            [_currentRosters removeObject:mutableString.copy];
            if ([_offlineRosters containsObject:mutableString.copy]) {
                [_offlineRosters removeObject:mutableString.copy];
            }
        }
    } else {
        if (![_offlineRosters containsObject:mutableString.copy]) {
            [_offlineRosters addObject:mutableString.copy];
            [_currentRosters addObject:mutableString.copy];
            if ([_onlineRosters containsObject:mutableString.copy]) {
                [_onlineRosters removeObject:mutableString.copy];
            }
        }
    }
    dispatch_sync(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
    });
}

- (void)refresh {
    dispatch_sync(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];

    });
}

@end


//A 用户B:用户B收到好友请求消息的时候,用户B点击”拒绝”,然后我们会调用- (void) rejectPresenceSubscriptionRequestFrom:(XMPPJID *)jid这个方法,我们想用户A发送拒绝的消息.同时要删除好友列表中用户A,有人会问用户A与B现在不是还没有好友关系吗?为什么用户B的好友列表中会有A?原因是这样的,当用户A发送好友请求的时候,用户B的列表就有了用户A,不过订阅状态却是None,这时候,我们需要删除好友A.删除好友,这里可不是取消订阅,而是删除.- (void)removeUser:(XMPPJID *)jid;
// 这里用了一个 currentRosters 可变数组.在第一次进入该 Controller 时,记录所有的用户信息.然后在- checkOnlineStatus方法中,把在线的用户从 currentRosters中删除,仅保留为上线用户.这样,在每当有用户上线,就会通知 APPDelegate 中的- didReceivePresence方法来判断是否符合上线或下线的条件,最后把符合条件的用户使用回调 - onOrOff 方法传回,再操作删除还是添加 currentRosters 可变数组
